home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / pyxmpp / jabber / muc.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2008-10-13  |  16.4 KB  |  505 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __revision__ = '$Id: muc.py 647 2006-08-26 18:27:39Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. import logging
  7. from pyxmpp.presence import Presence
  8. from pyxmpp.message import Message
  9. from pyxmpp.iq import Iq
  10. from pyxmpp.jid import JID
  11. from pyxmpp.xmlextra import xml_element_ns_iter
  12. from pyxmpp.jabber.muccore import MucPresence, MucUserX, MucItem, MucStatus
  13. from pyxmpp.jabber.muccore import MUC_OWNER_NS
  14. from pyxmpp.jabber.dataforms import DATAFORM_NS, Form
  15. import weakref
  16.  
  17. class MucRoomHandler:
  18.     
  19.     def __init__(self):
  20.         self.room_state = None
  21.         self._MucRoomHandler__logger = logging.getLogger('pyxmpp.jabber.MucRoomHandler')
  22.  
  23.     
  24.     def assign_state(self, state_obj):
  25.         self.room_state = state_obj
  26.  
  27.     
  28.     def room_created(self, stanza):
  29.         _unused = stanza
  30.         self.room_state.request_instant_room()
  31.  
  32.     
  33.     def configuration_form_received(self, form):
  34.         pass
  35.  
  36.     
  37.     def room_configured(self):
  38.         pass
  39.  
  40.     
  41.     def user_joined(self, user, stanza):
  42.         pass
  43.  
  44.     
  45.     def user_left(self, user, stanza):
  46.         pass
  47.  
  48.     
  49.     def role_changed(self, user, old_role, new_role, stanza):
  50.         pass
  51.  
  52.     
  53.     def affiliation_changed(self, user, old_aff, new_aff, stanza):
  54.         pass
  55.  
  56.     
  57.     def nick_change(self, user, new_nick, stanza):
  58.         pass
  59.  
  60.     
  61.     def nick_changed(self, user, old_nick, stanza):
  62.         pass
  63.  
  64.     
  65.     def presence_changed(self, user, stanza):
  66.         pass
  67.  
  68.     
  69.     def subject_changed(self, user, stanza):
  70.         pass
  71.  
  72.     
  73.     def message_received(self, user, stanza):
  74.         pass
  75.  
  76.     
  77.     def room_configuration_error(self, stanza):
  78.         self.error(stanza)
  79.  
  80.     
  81.     def error(self, stanza):
  82.         err = stanza.get_error()
  83.         self._MucRoomHandler__logger.debug('Error from: %r Condition: %r' % (stanza.get_from(), err.get_condition))
  84.  
  85.  
  86.  
  87. class MucRoomUser:
  88.     
  89.     def __init__(self, presence_or_user_or_jid):
  90.         if isinstance(presence_or_user_or_jid, MucRoomUser):
  91.             self.presence = presence_or_user_or_jid.presence
  92.             self.role = presence_or_user_or_jid.role
  93.             self.affiliation = presence_or_user_or_jid.affiliation
  94.             self.room_jid = presence_or_user_or_jid.room_jid
  95.             self.real_jid = presence_or_user_or_jid.real_jid
  96.             self.nick = presence_or_user_or_jid.nick
  97.             self.new_nick = None
  98.         else:
  99.             self.affiliation = 'none'
  100.             self.presence = None
  101.             self.real_jid = None
  102.             self.new_nick = None
  103.             if isinstance(presence_or_user_or_jid, JID):
  104.                 self.nick = presence_or_user_or_jid.resource
  105.                 self.room_jid = presence_or_user_or_jid
  106.                 self.role = 'none'
  107.             elif isinstance(presence_or_user_or_jid, Presence):
  108.                 self.nick = None
  109.                 self.room_jid = None
  110.                 self.role = 'participant'
  111.                 self.update_presence(presence_or_user_or_jid)
  112.             else:
  113.                 raise TypeError, 'Bad argument type for MucRoomUser constructor'
  114.  
  115.     
  116.     def update_presence(self, presence):
  117.         self.presence = MucPresence(presence)
  118.         t = presence.get_type()
  119.         if t == 'unavailable':
  120.             self.role = 'none'
  121.             self.affiliation = 'none'
  122.         
  123.         self.room_jid = self.presence.get_from()
  124.         self.nick = self.room_jid.resource
  125.         mc = self.presence.get_muc_child()
  126.         if isinstance(mc, MucUserX):
  127.             items = mc.get_items()
  128.             for item in items:
  129.                 if not isinstance(item, MucItem):
  130.                     continue
  131.                 
  132.                 if item.role:
  133.                     self.role = item.role
  134.                 
  135.                 if item.affiliation:
  136.                     self.affiliation = item.affiliation
  137.                 
  138.                 if item.jid:
  139.                     self.real_jid = item.jid
  140.                 
  141.                 if item.nick:
  142.                     self.new_nick = item.nick
  143.                 
  144.             
  145.         
  146.  
  147.     
  148.     def same_as(self, other):
  149.         return self.room_jid == other.room_jid
  150.  
  151.  
  152.  
  153. class MucRoomState:
  154.     
  155.     def __init__(self, manager, own_jid, room_jid, handler):
  156.         self.own_jid = own_jid
  157.         self.room_jid = room_jid
  158.         self.handler = handler
  159.         self.manager = weakref.proxy(manager)
  160.         self.joined = False
  161.         self.subject = None
  162.         self.users = { }
  163.         self.me = MucRoomUser(room_jid)
  164.         self.configured = None
  165.         self.configuration_form = None
  166.         handler.assign_state(self)
  167.         self._MucRoomState__logger = logging.getLogger('pyxmpp.jabber.MucRoomState')
  168.  
  169.     
  170.     def get_user(self, nick_or_jid, create = False):
  171.         if isinstance(nick_or_jid, JID):
  172.             if not nick_or_jid.resource:
  173.                 return None
  174.             
  175.             for u in self.users.values():
  176.                 if nick_or_jid in (u.room_jid, u.real_jid):
  177.                     return u
  178.                     continue
  179.             
  180.             if create:
  181.                 return MucRoomUser(nick_or_jid)
  182.             else:
  183.                 return None
  184.         
  185.         return self.users.get(nick_or_jid)
  186.  
  187.     
  188.     def set_stream(self, stream):
  189.         _unused = stream
  190.         if self.joined and self.handler:
  191.             self.handler.user_left(self.me, None)
  192.         
  193.         self.joined = False
  194.  
  195.     
  196.     def join(self, password = None, history_maxchars = None, history_maxstanzas = None, history_seconds = None, history_since = None):
  197.         if self.joined:
  198.             raise RuntimeError, 'Room is already joined'
  199.         
  200.         p = MucPresence(to_jid = self.room_jid)
  201.         p.make_join_request(password, history_maxchars, history_maxstanzas, history_seconds, history_since)
  202.         self.manager.stream.send(p)
  203.  
  204.     
  205.     def leave(self):
  206.         if self.joined:
  207.             p = MucPresence(to_jid = self.room_jid, stanza_type = 'unavailable')
  208.             self.manager.stream.send(p)
  209.         
  210.  
  211.     
  212.     def send_message(self, body):
  213.         m = Message(to_jid = self.room_jid.bare(), stanza_type = 'groupchat', body = body)
  214.         self.manager.stream.send(m)
  215.  
  216.     
  217.     def set_subject(self, subject):
  218.         m = Message(to_jid = self.room_jid.bare(), stanza_type = 'groupchat', subject = subject)
  219.         self.manager.stream.send(m)
  220.  
  221.     
  222.     def change_nick(self, new_nick):
  223.         new_room_jid = JID(self.room_jid.node, self.room_jid.domain, new_nick)
  224.         p = Presence(to_jid = new_room_jid)
  225.         self.manager.stream.send(p)
  226.  
  227.     
  228.     def get_room_jid(self, nick = None):
  229.         if nick is None:
  230.             return self.room_jid
  231.         
  232.         return JID(self.room_jid.node, self.room_jid.domain, nick)
  233.  
  234.     
  235.     def get_nick(self):
  236.         return self.room_jid.resource
  237.  
  238.     
  239.     def process_available_presence(self, stanza):
  240.         fr = stanza.get_from()
  241.         if not fr.resource:
  242.             return None
  243.         
  244.         nick = fr.resource
  245.         user = self.users.get(nick)
  246.         if user:
  247.             old_user = MucRoomUser(user)
  248.             user.update_presence(stanza)
  249.             user.nick = nick
  250.         else:
  251.             old_user = None
  252.             user = MucRoomUser(stanza)
  253.             self.users[user.nick] = user
  254.         self.handler.presence_changed(user, stanza)
  255.         if fr == self.room_jid and not (self.joined):
  256.             self.joined = True
  257.             self.me = user
  258.             mc = stanza.get_muc_child()
  259.             if self.configured is None:
  260.                 self.configured = True
  261.             
  262.         
  263.         if not old_user or old_user.role == 'none':
  264.             self.handler.user_joined(user, stanza)
  265.         elif old_user.nick != user.nick:
  266.             self.handler.nick_changed(user, old_user.nick, stanza)
  267.             if old_user.room_jid == self.room_jid:
  268.                 self.room_jid = fr
  269.             
  270.         
  271.         if old_user.role != user.role:
  272.             self.handler.role_changed(user, old_user.role, user.role, stanza)
  273.         
  274.         if old_user.affiliation != user.affiliation:
  275.             self.handler.affiliation_changed(user, old_user.affiliation, user.affiliation, stanza)
  276.         
  277.  
  278.     
  279.     def process_unavailable_presence(self, stanza):
  280.         fr = stanza.get_from()
  281.         if not fr.resource:
  282.             return None
  283.         
  284.         nick = fr.resource
  285.         user = self.users.get(nick)
  286.         if user:
  287.             old_user = MucRoomUser(user)
  288.             user.update_presence(stanza)
  289.             self.handler.presence_changed(user, stanza)
  290.             if user.new_nick:
  291.                 mc = stanza.get_muc_child()
  292.                 if isinstance(mc, MucUserX):
  293.                     renames = _[1]
  294.                     if renames:
  295.                         self.users[user.new_nick] = user
  296.                         del self.users[nick]
  297.                         return None
  298.                     
  299.                 
  300.             
  301.         else:
  302.             old_user = None
  303.             user = MucRoomUser(stanza)
  304.             self.users[user.nick] = user
  305.             self.handler.presence_changed(user, stanza)
  306.         if fr == self.room_jid and self.joined:
  307.             self.joined = False
  308.             self.handler.user_left(user, stanza)
  309.             self.manager.forget(self)
  310.             self.me = user
  311.         elif old_user:
  312.             self.handler.user_left(user, stanza)
  313.         
  314.  
  315.     
  316.     def process_groupchat_message(self, stanza):
  317.         fr = stanza.get_from()
  318.         user = self.get_user(fr, True)
  319.         s = stanza.get_subject()
  320.         if s:
  321.             self.subject = s
  322.             self.handler.subject_changed(user, stanza)
  323.         else:
  324.             self.handler.message_received(user, stanza)
  325.  
  326.     
  327.     def process_error_message(self, stanza):
  328.         self.handler.error(stanza)
  329.  
  330.     
  331.     def process_error_presence(self, stanza):
  332.         self.handler.error(stanza)
  333.  
  334.     
  335.     def process_configuration_form_success(self, stanza):
  336.         if stanza.get_query_ns() != MUC_OWNER_NS:
  337.             raise ValueError, 'Bad result namespace'
  338.         
  339.         query = stanza.get_query()
  340.         form = None
  341.         for el in xml_element_ns_iter(query.children, DATAFORM_NS):
  342.             form = Form(el)
  343.         
  344.         if not form:
  345.             raise ValueError, 'No form received'
  346.         
  347.         self.configuration_form = form
  348.         self.handler.configuration_form_received(form)
  349.  
  350.     
  351.     def process_configuration_form_error(self, stanza):
  352.         self.handler.error(stanza)
  353.  
  354.     
  355.     def request_configuration_form(self):
  356.         iq = Iq(to_jid = self.room_jid.bare(), stanza_type = 'get')
  357.         iq.new_query(MUC_OWNER_NS, 'query')
  358.         self.manager.stream.set_response_handlers(iq, self.process_configuration_form_success, self.process_configuration_form_error)
  359.         self.manager.stream.send(iq)
  360.         return iq.get_id()
  361.  
  362.     
  363.     def process_configuration_success(self, stanza):
  364.         _unused = stanza
  365.         self.configured = True
  366.         self.handler.room_configured()
  367.  
  368.     
  369.     def process_configuration_error(self, stanza):
  370.         self.handler.room_configuration_error(stanza)
  371.  
  372.     
  373.     def configure_room(self, form):
  374.         if form.type == 'cancel':
  375.             return None
  376.         elif form.type != 'submit':
  377.             raise ValueError, "A 'submit' form required to configure a room"
  378.         
  379.         iq = Iq(to_jid = self.room_jid.bare(), stanza_type = 'set')
  380.         query = iq.new_query(MUC_OWNER_NS, 'query')
  381.         form.as_xml(query)
  382.         self.manager.stream.set_response_handlers(iq, self.process_configuration_success, self.process_configuration_error)
  383.         self.manager.stream.send(iq)
  384.         return iq.get_id()
  385.  
  386.     
  387.     def request_instant_room(self):
  388.         if self.configured:
  389.             raise RuntimeError, 'Instant room may be requested for unconfigured room only'
  390.         
  391.         form = Form('submit')
  392.         return self.configure_room(form)
  393.  
  394.  
  395.  
  396. class MucRoomManager:
  397.     
  398.     def __init__(self, stream):
  399.         self.rooms = { }
  400.         (self.stream, self.jid) = (None, None)
  401.         self.set_stream(stream)
  402.         self._MucRoomManager__logger = logging.getLogger('pyxmpp.jabber.MucRoomManager')
  403.  
  404.     
  405.     def set_stream(self, stream):
  406.         self.jid = stream.me
  407.         self.stream = stream
  408.         for r in self.rooms.values():
  409.             r.set_stream(stream)
  410.         
  411.  
  412.     
  413.     def set_handlers(self, priority = 10):
  414.         self.stream.set_message_handler('groupchat', self._MucRoomManager__groupchat_message, None, priority)
  415.         self.stream.set_message_handler('error', self._MucRoomManager__error_message, None, priority)
  416.         self.stream.set_presence_handler('available', self._MucRoomManager__presence_available, None, priority)
  417.         self.stream.set_presence_handler('unavailable', self._MucRoomManager__presence_unavailable, None, priority)
  418.         self.stream.set_presence_handler('error', self._MucRoomManager__presence_error, None, priority)
  419.  
  420.     
  421.     def join(self, room, nick, handler, password = None, history_maxchars = None, history_maxstanzas = None, history_seconds = None, history_since = None):
  422.         if not (room.node) or room.resource:
  423.             raise ValueError, 'Invalid room JID'
  424.         
  425.         room_jid = JID(room.node, room.domain, nick)
  426.         cur_rs = self.rooms.get(room_jid.bare().as_unicode())
  427.         if cur_rs and cur_rs.joined:
  428.             raise RuntimeError, 'Room already joined'
  429.         
  430.         rs = MucRoomState(self, self.stream.me, room_jid, handler)
  431.         self.rooms[room_jid.bare().as_unicode()] = rs
  432.         rs.join(password, history_maxchars, history_maxstanzas, history_seconds, history_since)
  433.         return rs
  434.  
  435.     
  436.     def get_room_state(self, room):
  437.         return self.rooms.get(room.bare().as_unicode())
  438.  
  439.     
  440.     def forget(self, rs):
  441.         
  442.         try:
  443.             del self.rooms[rs.room_jid.bare().as_unicode()]
  444.         except KeyError:
  445.             pass
  446.  
  447.  
  448.     
  449.     def __groupchat_message(self, stanza):
  450.         fr = stanza.get_from()
  451.         key = fr.bare().as_unicode()
  452.         rs = self.rooms.get(key)
  453.         if not rs:
  454.             self._MucRoomManager__logger.debug('groupchat message from unknown source')
  455.             return False
  456.         
  457.         rs.process_groupchat_message(stanza)
  458.         return True
  459.  
  460.     
  461.     def __error_message(self, stanza):
  462.         fr = stanza.get_from()
  463.         key = fr.bare().as_unicode()
  464.         rs = self.rooms.get(key)
  465.         if not rs:
  466.             return False
  467.         
  468.         rs.process_error_message(stanza)
  469.         return True
  470.  
  471.     
  472.     def __presence_error(self, stanza):
  473.         fr = stanza.get_from()
  474.         key = fr.bare().as_unicode()
  475.         rs = self.rooms.get(key)
  476.         if not rs:
  477.             return False
  478.         
  479.         rs.process_error_presence(stanza)
  480.         return True
  481.  
  482.     
  483.     def __presence_available(self, stanza):
  484.         fr = stanza.get_from()
  485.         key = fr.bare().as_unicode()
  486.         rs = self.rooms.get(key)
  487.         if not rs:
  488.             return False
  489.         
  490.         rs.process_available_presence(MucPresence(stanza))
  491.         return True
  492.  
  493.     
  494.     def __presence_unavailable(self, stanza):
  495.         fr = stanza.get_from()
  496.         key = fr.bare().as_unicode()
  497.         rs = self.rooms.get(key)
  498.         if not rs:
  499.             return False
  500.         
  501.         rs.process_unavailable_presence(MucPresence(stanza))
  502.         return True
  503.  
  504.  
  505.